#include "StdAfx.h"
#include "Graphics.h"
#include "WorldPosition.h"


namespace Renderer
{

	WorldPosition::WorldPosition()
	{
		this->isBillboard = false;
		combineMatrix1 = combineMatrix2 = NULL;

		Move(0.0f, 0.0f, 0.0f);
		Rotate(0.0f, 0.0f, 0.0f);
		Scale(1.0f, 1.0f, 1.0f);

		Update();
	}

	D3DXMATRIX* WorldPosition::GetMatrix(Graphics * graphics)
	{
		Update(graphics);
		return &worldMatrix;
	}
	void WorldPosition::SetCombineMatrix1(D3DXMATRIX* matrix)
	{
		combineMatrix1 = matrix;
	}
	void WorldPosition::SetCombineMatrix2(D3DXMATRIX* matrix)
	{
		combineMatrix2 = matrix;
	}

	bool WorldPosition::Copy(WorldPosition * destPos)
	{
		destPos->Move(posX, posY, posZ);
		destPos->Rotate(rotX, rotY, rotZ);
		destPos->Scale(scaleX, scaleY, scaleZ);
		destPos->EnableBillboard(isBillboard);

		return true;
	}

	void WorldPosition::Move(float posX, float posY, float posZ)
	{
		this->posX = posX;
		this->posY = posY;
		this->posZ = posZ;

		D3DXMatrixTranslation(&translationMatrix, posX, posY, posZ);
	}
	void WorldPosition::MoveRel(float addX, float addY, float addZ)
	{
		Move(posX + addX, posY + addY, posZ + addZ);
	}

	void WorldPosition::Rotate(float rotX, float rotY, float rotZ)
	{
		this->rotX = rotX;
		this->rotY = rotY;
		this->rotZ = rotZ;

		D3DXMatrixRotationYawPitchRoll(&rotationMatrix, rotY, rotX, rotZ);
	}
	void WorldPosition::RotateRel(float addX, float addY, float addZ)
	{
		Rotate(rotX + addX, rotY + addY, rotZ + addZ);
	}

	void WorldPosition::Scale(float scaleX, float scaleY, float scaleZ)
	{
		this->scaleX = scaleX;
		this->scaleY = scaleY;
		this->scaleZ = scaleZ;

		D3DXMatrixScaling(&scaleMatrix, scaleX, scaleY, scaleZ);
	}
	void WorldPosition::ScaleRel(float addX, float addY, float addZ)
	{
		Scale(scaleX + addX, scaleY + addY, scaleZ + addZ);
	}

	void WorldPosition::Update(Graphics* graphics)
	{
		D3DXMATRIX viewMat, transposedMat;

		//if billoard
		if(isBillboard)
		{
			IDirect3DDevice9* device = graphics->GetDeviceCOM();
			if(graphics != NULL && device != NULL)
			{
				//get view Matrix
				device->GetTransform(D3DTS_VIEW, &viewMat);
				//transpose view matrix;
				D3DXMatrixTranspose(&transposedMat, &viewMat);
				//      X
				//      X
				//      X
				//X X X
				//Zero the X's out
				transposedMat._41 = transposedMat._42 = transposedMat._43 = transposedMat._14 = transposedMat._24 = transposedMat._34 = 0.0f;
			}
			else
			{
				D3DXMatrixIdentity(&transposedMat);
			}
		}

		//worldMatrix = scale * rotation
		D3DXMatrixMultiply(&worldMatrix, &scaleMatrix, &rotationMatrix);

		//worldMatrix *= transpose
		//take the new world matrix and orientate towards the camera
		if(isBillboard)
			D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &transposedMat);

		//worldMatrix *= translation
		D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &translationMatrix);


		//if used multply with combined matrices
		if(combineMatrix1 != NULL)
			D3DXMatrixMultiply(&worldMatrix, &worldMatrix, combineMatrix1);
		if(combineMatrix2 != NULL)
			D3DXMatrixMultiply(&worldMatrix, &worldMatrix, combineMatrix2);
	}
	void WorldPosition::EnableBillboard(bool enable)
	{
		isBillboard = enable;
	}

	float WorldPosition::GetXPos() const { return this->posX; }
	float WorldPosition::GetYPos() const { return posY; }
	float WorldPosition::GetZPos() const { return posZ; }
	float WorldPosition::GetXRotation() const { return rotX; }
	float WorldPosition::GetYRotation() const { return rotY; }
	float WorldPosition::GetZRotation() const { return rotZ; }
	float WorldPosition::GetXScale() const { return scaleX; }
	float WorldPosition::GetYScale() const { return scaleY; }
	float WorldPosition::GetZScale() const { return scaleZ; }

}